-
Notifications
You must be signed in to change notification settings - Fork 28
Introduce AutoMonitor for simpler enablement of Application Signals #297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…h AutoMonitor and AnnotationMutators, check if safe to mutate before applying custom selector, run opt out tests for each type of workload, test opt out by disabling monitorallservices
CustomSelectors should obey autoRestart, autoAnnotateAutoInstrumentation shouldn't. Rename MonitorInterface to InstrumentationAnnotator. Add docs.
…ntation container validation by default. This is required for automonitor to work, because it tries to apply all init containers to each selected pod.
… update pod templates in workloads.
…el custom selector should not update pod template
…art namespace for autoAnnotateAutoInstrumentation.
main.go
Outdated
if err := json.Unmarshal([]byte(autoAnnotationConfigStr), &autoAnnotationConfig); err != nil { | ||
setupLog.Error(err, "Unable to unmarshal auto-annotation config") | ||
} else { | ||
// todo: technically a breaking change, because previously an empty autoAnnotationConfig would clear all annotations, but automonitor does not reproduce this behavior by default because it requires restartPods to be enabled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I don't think we need this todo here. We expect this and aligned that this is expected. We aren't going to have "parity" by clearing all annotations when restartPods is false.
main.go
Outdated
if os.Getenv("DISABLE_AUTO_ANNOTATION") == "true" { | ||
setupLog.Info("Auto-annotation is disabled") | ||
} else if autoAnnotationConfigStr != "" { | ||
if err := json.Unmarshal([]byte(autoAnnotationConfigStr), &autoAnnotationConfig); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if an auto annotation config exists, and we are unable to marshal shouldn't we just return the error here? Why keep going?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because we might want to use AutoMonitor instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i could go either way on this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I'm thinking if a customer has an auto annotation config -- the intention is to use auto annotation and if that fails we should just return an error. But not a big deal
…il.go in auto package. Add unit tests
ef66e90
to
0e27206
Compare
main.go
Outdated
if os.Getenv("DISABLE_AUTO_ANNOTATION") == "true" { | ||
setupLog.Info("Auto-annotation is disabled") | ||
} else if autoAnnotationConfigStr != "" { | ||
if err := json.Unmarshal([]byte(autoAnnotationConfigStr), &autoAnnotationConfig); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I'm thinking if a customer has an auto annotation config -- the intention is to use auto annotation and if that fails we should just return an error. But not a big deal
assert.NotNil(t, annotator, "Expected non-nil annotator") | ||
|
||
// Check type using type assertion | ||
actualType := fmt.Sprintf("%T", annotator) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Would prefer to use reflection or some enum that checks the actual type instead of these string representations. If we ever rename the struct or package or move it to a different package, these tests will break.
Could do something like
expectedType: reflect.TypeOf(auto.AnnotationMutators{})
...
assert.Equals(t, tt.expectedType, reflect.TypeOf(annotator))
or
type annotatorType int
const (
unset annotatorType = iota
mutators
monitor
)
...
switch annotator.(type) {
case *auto.AnnotationMutators:
assert.Equals(t, mutators, tt.expectedType)
}
} | ||
|
||
if autoAnnotationConfigStr == "" { | ||
return nil, fmt.Errorf("auto-annotation configuration not provided, disabling AutoAnnotation") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this get logged as an error when the environment variable case is logged as an info message? This seems like a common case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree that this probably doesnt need to be an error.
But dont think this will be very common since our add-on/chart will set the default for this as the java: {deployments:[], ...}
string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually we do the same below for autoAnnotationConfig.Empty()
and that will be true.
return typesSelected | ||
} | ||
|
||
func (c AnnotationConfig) Empty() bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
super minor nit: Naming might suggest that it would empty the configuration.
func (c AnnotationConfig) Empty() bool { | |
func (c AnnotationConfig) IsEmpty() bool { |
/ |
Description of changes: Introduce Auto Monitor for Application Signals on K8s which provides an easier onboarding experience. When enabled, the Operator can auto-instrument K8s workloads that are associated with K8s services as they come up automatically without requiring explicit opt-in via workload specific annotations.
The operator now accepts a new arg
auto-monitor-config
that has the following structure:monitorAllServices
: Enable AutoMonitor for all services in the cluster i.e. for any K8s workloads that are brought up in the cluster, auto-instrument them. Defaults to false i.e. not enabled.langugages
: Specify the list of languages that AutoMonitor should inject auto-instrumentation for. Defaults to all supported languages.restartPods
: When enabled, restart pods that are already running on the cluster corresponding to K8s workloads that now fall under the scope of AutoMonitor. Defaults to false i.e. not enabled.customSelector
: Provides more granular control to explicitly specify namespaces and workloads that should be auto-instrumented. Can be specified even ifmonitorAllServices
is disabled.exclude
: Similar tocustomSelector
, but is instead used to deny specific namespaces or workloads from getting auto-instrumented whenmonitorAllServices
is enabled. Takes precedence overcustomSelector
in the case of conflicts.Additional Notes:
customSelector
withrestartPods
enabled serves as a replacement for the existingauto-annotation-config
arg.auto-annotation-config
will be deprecated entirely in a future release. Using both is consider invalid and will continue to respectauto-annotation-config
in such scenarios.monitorAllServices
by default does not auto-instrument services in thekube-system
andamazon-cloudwatch
namespaces. If you require services in these namespaces to be auto-instrumented, you can explicitly specify them usingcustomSelector
.By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.